import numpy as np
import matplotlib.pyplot as plt
from matplotlib import style
import warnings
from collections import Counter
import pandas as pd
import random
style.use('fivethirtyeight')

# Tutorial can be found at the following link: https://pythonprogramming.net/testing-our-k-nearest-neighbors-machine-learning-tutorial/?completed=/coding-k-nearest-neighbors-machine-learning-tutorial/

def k_nearest_neighbors(data, predict, k=3):
    if len(data) >= k:
        warnings.warn('K is set to a value less than total voting groups!')
    distances = []
    for group in data:
        for features in data[group]:
            euclidean_distance = np.linalg.norm(np.array(features)-np.array(predict))
            distances.append([euclidean_distance,group])
    votes = [i[1] for i in sorted(distances)[:k]]
    vote_result = Counter(votes).most_common(1)[0][0]
    return vote_result

df = pd.read_csv('/Users/nickwalker/Desktop/Data Sets/Breast Cancer Wisconsin Data.csv')
df.replace('?',-99999,inplace=True)
df.drop(['id'],1,inplace=True)
full_data = df.astype(float).values.tolist()
    # this converts the data to float and to list of lists
        # must convert to float because some of the numbers were still of the string datatype

# shuffle the data:
random.shuffle(full_data)
# test data is 20% of total data:
test_size = 0.2
# here we populate the dictionaries -- the 2 is for benign tumors and the 4 is for malignant tumors
train_set = {2:[], 4:[]}
test_set = {2:[], 4:[]}
train_data = full_data[:-int(test_size*len(full_data))]
test_data = full_data[-int(test_size*len(full_data)):]

for i in train_data:
    train_set[i[-1]].append(i[:-1])
for i in test_data:
    test_set[i[-1]].append(i[:-1])
# now we have dictionaries populated where the key is the class and the values are the attributes

correct = 0
total = 0

for group in test_set:
    for data in test_set[group]:
        vote = k_nearest_neighbors(train_set, data, k=5)
        if group == vote:
            correct += 1
        total += 1
print ('Accuracy:', correct/total)
